package com.huawang.ecolink.apps.controllers.modelica;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.huawang.ecolink.apps.request.mapping.ElementListParam;
import com.huawang.ecolink.apps.request.mapping.ImportSysMlAddVo;
import com.huawang.ecolink.apps.request.mapping.MappingRelationshipParam;
import com.huawang.ecolink.apps.response.BaseResponse;
import com.huawang.ecolink.apps.response.modelica.*;
import com.huawang.ecolink.apps.service.modelica.MappingService;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.net.URLDecoder;
import java.util.*;

@Api(tags = "映射接口")
@RestController
@RequestMapping("/mlink")
@Slf4j
public class MappingController {
    public static final String INSTANCE_ID = "instanceID";
    public static final String PROJECT_ID = "projectID";
    @Autowired
    private MappingService mappingService;

    protected static ObjectMapper objectMapper = new ObjectMapper();

    /*** 
     * @Description: 获取SysML模型结构树
     * @param projectId String
     * @param instanceId String
     * @param flag String
     * @return: com.huawang.ecolink.apps.response.BaseResponse<com.huawang.ecolink.apps.response.modelica.SysMLTreeVO>
     * @throws:
     */
    @ApiOperation("获取SysML镜像模型")
    @GetMapping("/modelica/getSysML/tree")
    @ApiImplicitParams({@ApiImplicitParam(name = PROJECT_ID, value = "项目id", required = true), @ApiImplicitParam(name = INSTANCE_ID, value = "元素ID", required = true), @ApiImplicitParam(name = "flag", value = "获取XML中关联关系标识，清空关系或删除关系后传‘1’，打开转换页面或者刷新时，传‘0’", required = true)})
    @ApiResponses({@ApiResponse(code = 1000, message = "OK", response = String.class),})
    public BaseResponse<SysMLTreeVO> getSysMLModelTree(@RequestParam(PROJECT_ID) String projectId, @RequestParam(INSTANCE_ID) String instanceId, @RequestParam("flag") String flag) {
        SysMLTreeVO sysMLTreeVO = mappingService.getSysMLModelInfo(projectId, instanceId, flag);
        return BaseResponse.success(sysMLTreeVO);
    }

    /***
     * @Description: 懒加载的方式获取SysML模型树, 避免加载过多导致时间慢
     * @param projectId String
     * @param instanceId String
     * @return: com.huawang.ecolink.apps.response.BaseResponse<java.util.List < com.huawang.ecolink.apps.response.modelica.SysMLTreeVO>>
     * @throws:
     */
    @ApiOperation("懒加载获取模型树")
    @GetMapping("/modelica/getSysML/childNode")
    @ApiImplicitParams({@ApiImplicitParam(name = PROJECT_ID, value = "项目id", required = true), @ApiImplicitParam(name = INSTANCE_ID, value = "元素ID", required = true),})
    @ApiResponses({@ApiResponse(code = 1000, message = "OK", response = List.class),})
    public BaseResponse<List<SysMLTreeVO>> getSysMlChildNode(@RequestParam(PROJECT_ID) String projectId, @RequestParam(INSTANCE_ID) String instanceId) {
        return BaseResponse.success(mappingService.getSysMLChildNode(projectId, instanceId));

    }

    /***
     * @Description: Modelica文件导入，并生成模型树根目录
     * @param reqBody String
     * @return: com.huawang.ecolink.apps.response.BaseResponse<com.huawang.ecolink.apps.response.modelica.MoClass>
     * @throws:
     */
    @ApiOperation("导入文件生成Modelica模型根目录")
    @PostMapping("/modelica/importfile/getRootTree")
    @ApiImplicitParams({@ApiImplicitParam(name = PROJECT_ID, value = "项目id", required = true), @ApiImplicitParam(name = "instID", value = "元素ID", required = true), @ApiImplicitParam(name = "moLibPath", value = "文件路径或者mo文件路径+文件名", required = true), @ApiImplicitParam(name = "name", value = "筛选条件", required = true),})
    @ApiResponses({@ApiResponse(code = 1000, message = "OK", response = MoClass.class),})
    public BaseResponse<MoClass> getTree(@RequestBody String reqBody) throws IOException {
        Map<String, String> transReq = null;
        reqBody = URLDecoder.decode(reqBody, "UTF-8");
        transReq = objectMapper.readValue(reqBody, HashMap.class);
        String projectId = transReq.get(PROJECT_ID);
        String instanceId = transReq.get("instID");
        String moLibPath = transReq.get("moLibPath");
        String name = transReq.get("name");
        return BaseResponse.success(mappingService.importMoToCreateTree(projectId, instanceId, moLibPath, name));
    }


    /***
     * @Description: 获取Modelica模型的子目录
     * @param reqBody String
     * @return: com.huawang.ecolink.apps.response.BaseResponse<java.util.List < com.huawang.ecolink.apps.response.modelica.MoClass>>
     * @throws:
     */
    @ApiOperation("获取Modelica模型树的子节点")
    @PostMapping("/modelica/importfile/getChilidTree")
    @ApiImplicitParams({@ApiImplicitParam(name = PROJECT_ID, value = "项目id", required = true), @ApiImplicitParam(name = "path", value = "上一个节点的path属性值", required = true),})
    @ApiResponses({@ApiResponse(code = 1000, message = "OK", response = MoClass.class),})
    public BaseResponse<List<MoClass>> getChilidTree(@RequestBody String reqBody) throws IOException {
        Map<String, String> transReq = null;
        reqBody = URLDecoder.decode(reqBody, "UTF-8");
        transReq = objectMapper.readValue(reqBody, HashMap.class);
        String projectId = transReq.get(PROJECT_ID);
        String path = transReq.get("path");
        return BaseResponse.success(mappingService.getMoChildNode(projectId, path));
    }

    /***
     * @Description: Modelica模型快速搜索功能
     * @param projectId String
     * @param searchName String
     * @return: com.huawang.ecolink.apps.response.BaseResponse<java.util.List < com.huawang.ecolink.apps.response.modelica.MoClass>>
     * @throws:
     */
    @ApiOperation("modelica模型树搜索列表")
    @GetMapping("/modelica/getMoTree/likebyname")
    @ApiImplicitParams({@ApiImplicitParam(name = PROJECT_ID, value = "项目id", required = true), @ApiImplicitParam(name = "searchName", value = "输入模糊搜索", required = true),})
    @ApiResponses({@ApiResponse(code = 1000, message = "OK", response = List.class),})
    public BaseResponse<List<MoClass>> getMoListByName(@RequestParam(PROJECT_ID) String projectId, @RequestParam("searchName") String searchName) {
        return BaseResponse.success(mappingService.getMoListByName(projectId, searchName));
    }


    /***
     * @Description: 将Modelica模型导入到SysML模型结构树中
     * @param importSysMlAddVo ImportSysMlAddVo
     * @return: com.huawang.ecolink.apps.response.BaseResponse<java.lang.String>
     * @throws:
     */
    @ApiOperation("导入MoClass对象到SysML")
    @PostMapping("/modelica/importSysML/add")
    @ApiResponses({@ApiResponse(code = 1000, message = "OK"),})
    public BaseResponse<String> importMoClassToSysMl(@RequestBody ImportSysMlAddVo importSysMlAddVo) {
        mappingService.importMoClassToSysMl(importSysMlAddVo);
        return BaseResponse.success();
    }

    /***
     * @Description: 清空Modelica文件导入生成的缓存
     * @param reqBody String
     * @return: com.huawang.ecolink.apps.response.BaseResponse<java.lang.String>
     * @throws:
     */
    @ApiOperation("清空Modelica模型集合")
    @PostMapping("/modelica/importfile/clear")
    @ApiImplicitParams({@ApiImplicitParam(name = PROJECT_ID, value = "项目id", required = true), @ApiImplicitParam(name = INSTANCE_ID, value = "元素ID", required = true),})
    @ApiResponses({@ApiResponse(code = 1000, message = "OK"),})
    public BaseResponse<String> clearTree(@RequestBody String reqBody) throws IOException {
        Map<String, String> transReq = null;
        transReq = objectMapper.readValue(reqBody, HashMap.class);
        String projectId = transReq.get(PROJECT_ID);
        String instanceId = transReq.get(INSTANCE_ID);
        mappingService.clearMoTree(projectId, instanceId);
        return BaseResponse.success();
    }

    /***
     * @Description: 保存导入到SysML结构树中的Modelica模型，进行落库
     * @param reqBody String
     * @return: com.huawang.ecolink.apps.response.BaseResponse<java.lang.String>
     * @throws:
     */
    @ApiOperation("导入新增对象到design中")
    @PostMapping("/modelica/import/save")
    @ApiImplicitParams({@ApiImplicitParam(name = PROJECT_ID, value = "项目id", required = true), @ApiImplicitParam(name = INSTANCE_ID, value = "元素ID", required = true), @ApiImplicitParam(name = "transactionId", value = "事务ID", required = true),})
    @ApiResponses({@ApiResponse(code = 1000, message = "OK"),})

    public BaseResponse<String> saveToDesgin(@RequestBody String reqBody) throws IOException {
        Map<String, String> transReq = null;
        transReq = objectMapper.readValue(reqBody, HashMap.class);
        String projectId = transReq.get(PROJECT_ID);
        String instanceId = transReq.get(INSTANCE_ID);
        String transactionId = transReq.get("transactionId");
        mappingService.saveToDesgin(projectId, instanceId, transactionId);
        return BaseResponse.success();
    }

    /***
     * @Description: 判断是否存在映射关系
     * @param projectId String
     * @param instanceId String
     * @return: com.huawang.ecolink.apps.response.BaseResponse<java.lang.Boolean>
     * @throws:
     */
    @ApiOperation("判断是否存在关联关系")
    @GetMapping("/modelica/mapping/isexist")
    @ApiImplicitParams({@ApiImplicitParam(name = PROJECT_ID, value = "项目id", required = true), @ApiImplicitParam(name = INSTANCE_ID, value = "元素ID", required = true),})
    @ApiResponses({@ApiResponse(code = 1000, message = "OK", response = Boolean.class),})

    public BaseResponse<Boolean> mappingIsexist(@RequestParam(PROJECT_ID) String projectId, @RequestParam(INSTANCE_ID) String instanceId) {
        return BaseResponse.success(mappingService.mappingIsexist(projectId, instanceId));
    }


    /***
     * @Description: 获取Modelica转成SysML模型的图形信息
     * @param projectId String
     * @param instanceId String
     * @return: com.huawang.ecolink.apps.response.BaseResponse<java.util.List < com.huawang.ecolink.apps.response.modelica.GraphicalInfoVO>>
     * @throws:
     */
    @ApiOperation("获取图形信息")
    @GetMapping("/modelica/graphical/getInfo")
    @ApiImplicitParams({@ApiImplicitParam(name = PROJECT_ID, value = "项目id", required = true), @ApiImplicitParam(name = INSTANCE_ID, value = "元素ID", required = true),})
    @ApiResponses({@ApiResponse(code = 1000, message = "OK", response = GraphicalInfoVO.class),})

    public BaseResponse<List<GraphicalInfoVO>> getGraphicalInfo(@RequestParam(PROJECT_ID) String projectId, @RequestParam(INSTANCE_ID) String instanceId) {
        return BaseResponse.success(mappingService.getPointInfo(projectId, instanceId));
    }


    /***
     * @Description: 创建映射关系
     * @param mappingRelationshipParam MappingRelationshipParam
     * @return: com.huawang.ecolink.apps.response.BaseResponse<java.lang.String>
     * @throws:
     */
    @ApiOperation("与modelica映射关系连接")
    @PostMapping("/modelica/link/add")
    @ApiImplicitParams({@ApiImplicitParam(name = PROJECT_ID, value = "项目id", required = true), @ApiImplicitParam(name = INSTANCE_ID, value = "元素ID", required = true), @ApiImplicitParam(name = "mappingPath", value = "modelica路径", required = true)})
    @ApiResponses({@ApiResponse(code = 1000, message = "OK", response = String.class),})
    public BaseResponse<String> createLinkStore(@RequestBody MappingRelationshipParam mappingRelationshipParam) {
        mappingService.addMappingRelationship(mappingRelationshipParam);
        return BaseResponse.success();
    }


    /***
     * @Description: 获取映射关系列表
     * @param projectId String
     * @param name String
     * @return: com.huawang.ecolink.apps.response.BaseResponse<java.util.List < com.huawang.ecolink.apps.response.modelica.MappingRalationshipVO>>
     * @throws:
     */
    @ApiOperation("获取映射关系列表")
    @GetMapping("/modelica/link/getInfo")
    @ApiImplicitParams({
            @ApiImplicitParam(name = PROJECT_ID, value = "项目id", required = true),
            @ApiImplicitParam(name = "name", value = "模糊查询名称,传''为全量查询", required = true),
    })
    @ApiResponses({
            @ApiResponse(code = 1000, message = "OK", response = MappingRalationshipVO.class),
    })
    public BaseResponse<List<MappingRalationshipVO>> getLinkByProjectID(@RequestParam(PROJECT_ID) String projectId, @RequestParam("name") String name) {


        return BaseResponse.success(mappingService.getLinkListByProjectId(projectId, name));
    }

    /***
     * @Description: 清空映射关系
     * @param reqBody String
     * @return: com.huawang.ecolink.apps.response.BaseResponse<java.lang.String>
     * @throws:
     */
    @ApiOperation("清空mapping关联")
    @PostMapping("/modelica/link/clear")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "projectID", value = "项目id", required = true)
    })
    @ApiResponses({
            @ApiResponse(code = 1000, message = "OK", response = String.class),
    })
    public BaseResponse<String> clearLink(@RequestBody String reqBody) throws IOException {
        Map<String, String> transReq = objectMapper.readValue(reqBody, HashMap.class);
        String projectId = transReq.get(PROJECT_ID);

        mappingService.clearMappingRelationship(projectId);
        return BaseResponse.success();
    }


    /***
     * @Description: 通过instanceId删除映射关系
     * @param reqBody String
     * @return: com.huawang.ecolink.apps.response.BaseResponse<java.lang.String>
     * @throws:
     */
    @ApiOperation("通过instanceID删除mapping关联")
    @PostMapping("/modelica/link/clearByInstanceID")
    @ApiImplicitParams({
            @ApiImplicitParam(name = PROJECT_ID, value = "项目id", required = true),
            @ApiImplicitParam(name = INSTANCE_ID, value = "元素ID", required = true)
    })
    @ApiResponses({
            @ApiResponse(code = 1000, message = "OK", response = String.class),
    })
    public BaseResponse<String> clearLinkByInstanceID(@RequestBody String reqBody) throws IOException {
        HashMap<String, String> transReq = objectMapper.readValue(reqBody, HashMap.class);
        String projectId = transReq.get(PROJECT_ID);
        String instanceId = transReq.get(INSTANCE_ID);

        mappingService.clearMappingRelationshipByInstanceID(projectId, instanceId);
        return BaseResponse.success();
    }

    /***
     * @Description: 关闭窗口时，将没有保存的数据缓存进行清空
     * @param reqBody String
     * @return: com.huawang.ecolink.apps.response.BaseResponse<java.lang.String>
     * @throws:
     */
    @ApiOperation("关闭窗口或者取消操作清空操作记录")
    @PostMapping("/modelica/operationRecords/clear")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "projectID", value = "项目id", dataTypeClass = String.class, required = true),
    })
    @ApiResponses({
            @ApiResponse(code = 1000, message = "OK", response = String.class),
    })
    public BaseResponse<String> clearOperationRecords(@RequestBody String reqBody) throws IOException {
        Map<String, String> transReq = objectMapper.readValue(reqBody, HashMap.class);
        String projectId = transReq.get(PROJECT_ID);
        mappingService.clearOperationRecords(projectId);
        return BaseResponse.success();
    }


    /***
     * @Description: 获取可以选择的类型列表
     * @param reqBody String
     * @return: java.util.Map<java.lang.String, java.lang.Object>
     * @throws:
     */
    @ApiOperation("获取可以选择的类型列表")
    @PostMapping("/modelica/slecect/getElementList")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "projectID", value = "参数和design一样", dataTypeClass = String.class, required = true),
    })
    @ApiResponses({
            @ApiResponse(code = 1000, message = "OK", response = HashMap.class),
    })
    public Map<String, Object> getElementList(@RequestBody String reqBody) throws IOException {
        Map<String, Object> transReq = null;
        transReq = objectMapper.readValue(reqBody, HashMap.class);
        String checkMethod = (String) transReq.get("checkMethod");
        List<String> classifierIds = (List<String>) transReq.get("classifierIds");
        String instanceId = (String) transReq.get("instanceId");
        String key = (String) transReq.get("key");
        String keyword = (String) transReq.get("keyword");
        String moreBtnCondition = (String) transReq.get("moreBtnCondition");
        Integer page = (Integer) transReq.get("page");
        String projectId = (String) transReq.get("projectId");
        Integer size = (Integer) transReq.get("size");
        ElementListParam elementListParam = new ElementListParam(checkMethod, classifierIds, instanceId, key, keyword, moreBtnCondition, page, projectId, size);
        return mappingService.getElementList(elementListParam);
    }

    /***
     * @Description: SysML结构树模糊搜索功能
     * @param projectId String
     * @param instanceId String
     * @param searchName String
     * @return: com.huawang.ecolink.apps.response.BaseResponse<java.util.List < com.huawang.ecolink.apps.response.modelica.ModelTreeVO>>
     * @throws:
     */
    @ApiOperation("根据名称模糊查询元素,返回符合条件的信息")
    @GetMapping("/modelica/getSysML/likebyname")
    @ApiImplicitParams({
            @ApiImplicitParam(name = PROJECT_ID, value = "项目id", required = true),
            @ApiImplicitParam(name = INSTANCE_ID, value = "元素ID", required = true),
            @ApiImplicitParam(name = "searchName", value = "输入模糊搜索", required = true),
    })
    @ApiResponses({
            @ApiResponse(code = 1000, message = "OK", response = List.class),
    })
    public BaseResponse<List<ModelTreeVO>> getSysMLSearchByName(@RequestParam("projectID") String projectId, @RequestParam("instanceID") String instanceId,
                                                                @RequestParam("searchName") String searchName) {

        return BaseResponse.success(mappingService.getSysMLSearchByName(projectId, instanceId, searchName));
    }


    /***
     * @Description: 通过instanceId获取Design模型路径
     * @param projectId String
     * @param instanceId String
     * @return: com.huawang.ecolink.apps.response.BaseResponse<java.util.List < com.huawang.ecolink.apps.response.modelica.ModelTreeVO>>
     * @throws:
     */
    @ApiOperation("根据instancId获取Design模型路径")
    @GetMapping("/modelica/getPath/selectById")
    @ApiImplicitParams({
            @ApiImplicitParam(name = PROJECT_ID, value = "项目id", required = true),
            @ApiImplicitParam(name = INSTANCE_ID, value = "元素ID", required = true),
    })
    @ApiResponses({
            @ApiResponse(code = 1000, message = "OK", response = List.class),
    })
    public BaseResponse<List<ModelTreeVO>> getSysMLSearchByName(@RequestParam("projectID") String projectId, @RequestParam("instanceID") String instanceId) {

        return BaseResponse.success(mappingService.getPath(projectId, instanceId));
    }

}
